#ifndef _h_bmp
#define _h_bmp

#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <cstdlib>
using namespace std;

struct Pixel {
	int r, g, b; // [0,255]
	Pixel()
		: r(0), g(0), b(0) { }
	Pixel(int r, int g, int b)
		: r(r), g(g), b(b) { }
};

struct Color {
	double r, g, b; // [0,1]
	Color()
		: r(0.), g(0.), b(0.) { }
	Color(double r, double g, double b)
		: r(r), g(g), b(b) {}
	Pixel to_pixel() const {
		return Pixel((int)(r*255.), (int)(g*255.), (int)(b*255.));
	}
	Color operator *(double c) const {
		return Color(r*c, g*c, b*c);
	}
	Color operator +(const Color &c) const {
		return Color(r+c.r, g+c.g, b+c.b);
	}
	Color operator *(const Color &c) const {
		return Color(r*c.r, g*c.g, b*c.b);
	}
	void merge(Color c) {
		r+=c.r;
		g+=c.g;
		b+=c.b;
		//r=1.-(1.-r)*(1.-c.r);
		//g=1.-(1.-g)*(1.-c.g);
		//b=1.-(1.-b)*(1.-c.b);
	}
};

struct Bmp {
	vector<vector<Pixel> > pixels;
	int h, w;
	Bmp()
		: h(0), w(0) { }
	Bmp(int h, int w) {
		this->h=h;
		this->w=w;
		pixels.resize(h);
		for(int i=0; i<h; ++i)
			pixels[i].resize(w);
	}
	void print_to_file(string file_name) {
		FILE *f;
		int filesize=54+3*w*h;
		unsigned char *img=(unsigned char*)malloc(3*w*h);
		for(int i=0; i<h; i++) {
			for(int j=0; j<w; j++) {
				int x=j, y=i;
				int r=pixels[i][j].r;
				int g=pixels[i][j].g;
				int b=pixels[i][j].b;
				img[(x+y*w)*3+2]=(unsigned char)(r);
				img[(x+y*w)*3+1]=(unsigned char)(g);
				img[(x+y*w)*3+0]=(unsigned char)(b);
			}
		}

		unsigned char bmpfileheader[14]={'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0};
		unsigned char bmpinfoheader[40]={40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};
		unsigned char bmppad[3] = {0,0,0};

		bmpfileheader[ 2] = (unsigned char)(filesize    );
		bmpfileheader[ 3] = (unsigned char)(filesize>> 8);
		bmpfileheader[ 4] = (unsigned char)(filesize>>16);
		bmpfileheader[ 5] = (unsigned char)(filesize>>24);
		bmpinfoheader[ 4] = (unsigned char)(       w    );
		bmpinfoheader[ 5] = (unsigned char)(       w>> 8);
		bmpinfoheader[ 6] = (unsigned char)(       w>>16);
		bmpinfoheader[ 7] = (unsigned char)(       w>>24);
		bmpinfoheader[ 8] = (unsigned char)(       h    );
		bmpinfoheader[ 9] = (unsigned char)(       h>> 8);
		bmpinfoheader[10] = (unsigned char)(       h>>16);
		bmpinfoheader[11] = (unsigned char)(       h>>24);

		f = fopen(file_name.c_str(),"wb");
		fwrite(bmpfileheader,1,14,f);
		fwrite(bmpinfoheader,1,40,f);
		for(int i=0; i<h; i++) {
			fwrite(img+(w*(h-i-1)*3),3,w,f);
			fwrite(bmppad,1,(4-(w*3)%4)%4,f);
		}
		fclose(f);
		free(img);
	}
};

#endif
